﻿using System;
using RentalSystem.Data.EF.Core;
using RentalSystem.Data.EF.Dao;
using RentalSystem.Data.EF;
using System.Transactions;

namespace RentalSystem.Data.SQLServer
{
    public class EFDataContext : IDataContext
    {
        private RentalDatabaseEntities repository;
        private TransactionScope scope;

        private IAgenciesDao agenciesDao;
        private IAgencyTypesDao agencyTypesDao;
        private ICommentsDao commentsDao;
        private ICustomerCardsDao customerCardsDao;
        private ICustomersDao customersDao;
        private ICustomerTypesDao customerTypesDao;
        private IDiscsDao discsDao;
        private IDiscTypesDao discTypesDao;
        private IHiresDao hiresDao;
        private IMoviesDao moviesDao;
        private IMovieKindsDao movieKindsDao;
        private IPersonsDao personsDao;
        private IStatisticsDao statisticsDao;
        private IUserLogsDao userLogsDao;
        private IUserLogTypesDao userLogTypesDao;
        private IUserRolesDao userRolesDao;
        private IUsersDao usersDao;
        private IVotesDao votesDao;
        private IWorkersDao workersDao;
        private IPagesContentsDao pagesContentsDao;
        private IFilesDao filesDao;
        private ISettingsDao settingsDao;

        public EFDataContext()
        {
            this.repository = new RentalDatabaseEntities();

            this.agenciesDao = new EFAgenciesDao(repository);
            this.agencyTypesDao = new EFAgencyTypesDao(repository);
            this.commentsDao = new EFCommentsDao(repository);
            this.customerCardsDao = new EFCustomerCardsDao(repository);
            this.customersDao = new EFCustomersDao(repository);
            this.customerTypesDao = new EFCustomerTypesDao(repository);
            this.discsDao = new EFDiscsDao(repository);
            this.discTypesDao = new EFDiscTypesDao(repository);
            this.hiresDao = new EFHiresDao(repository);
            this.moviesDao = new EFMoviesDao(repository);
            this.movieKindsDao = new EFMovieKindsDao(repository);
            this.personsDao = new EFPersonsDao(repository);
            this.statisticsDao = new EFStatisticsDao(repository);
            this.userLogsDao = new EFUserLogsDao(repository);
            this.userLogTypesDao = new EFUserLogTypesDao(repository);
            this.userRolesDao = new EFUserRolesDao(repository);
            this.usersDao = new EFUsersDao(repository);
            this.votesDao = new EFVotesDao(repository);
            this.workersDao = new EFWorkersDao(repository);
            this.pagesContentsDao = new EFPagesContentsDao(repository);
            this.filesDao = new EFFilesDao(repository);
            this.settingsDao = new EFSettingsDao(repository);
        }

        
        #region IDaoFactory

        public IAgenciesDao AgenciesDao
        {
            get { return this.agenciesDao; }
        }

        public IAgencyTypesDao AgencyTypesDao
        {
            get { return this.agencyTypesDao; }
        }

        public ICommentsDao CommentsDao
        {
            get { return this.commentsDao; }
        }

        public ICustomerCardsDao CustomerCardsDao
        {
            get { return this.customerCardsDao; }
        }

        public ICustomersDao CustomersDao
        {
            get { return this.customersDao; }
        }

        public ICustomerTypesDao CustomerTypesDao
        {
            get { return this.customerTypesDao; }
        }

        public IDiscsDao DiscsDao
        {
            get { return this.discsDao; }
        }

        public IDiscTypesDao DiscTypesDao
        {
            get { return this.discTypesDao; }
        }

        public IHiresDao HiresDao
        {
            get { return this.hiresDao; }
        }

        public IMoviesDao MoviesDao
        {
            get { return this.moviesDao; }
        }

        public IMovieKindsDao MovieKindsDao
        {
            get { return this.movieKindsDao; }
        }

        public IPersonsDao PersonsDao
        {
            get { return this.personsDao; }
        }

        public IStatisticsDao StatisticsDao
        {
            get { return this.statisticsDao; }
        }

        public IUserLogsDao UserLogsDao
        {
            get { return this.userLogsDao; }
        }

        public IUserLogTypesDao UserLogTypesDao
        {
            get { return this.userLogTypesDao; }
        }

        public IUserRolesDao UserRolesDao
        {
            get { return this.userRolesDao; }
        }

        public IUsersDao UsersDao
        {
            get { return this.usersDao; }
        }

        public IVotesDao VotesDao
        {
            get { return this.votesDao; }
        }

        public IWorkersDao WorkersDao
        {
            get { return this.workersDao; }
        }

        public IPagesContentsDao PagesContentsDao
        {
            get { return this.pagesContentsDao; }
        }

        public IFilesDao FilesDao
        {
            get { return this.filesDao; }
        }

        public ISettingsDao SettingsDao
        {
            get { return this.settingsDao; }
        }

        #endregion

        #region ITransaction

        public void StartTransaction()
        {
            scope = new TransactionScope();
        }

        public void Rollback()
        {
            if (scope == null)
                throw new InvalidOperationException("Rollback() before StartTransaction()");

            scope.Dispose();
        }

        public void Commit()
        {
            if (scope == null)
                throw new InvalidOperationException("Commit() before StartTransaction()");

            scope.Complete();
            scope.Dispose();
        }

        #endregion
    }
}
